<?php

require_once('jhtraq.php');
class JhtraqModelSvn extends JhtraqModelJhtraq
{

	function diff($old, $new)
	{
		foreach($old as $oindex => $ovalue)
		{
			$nkeys = array_keys($new, $ovalue);
			foreach($nkeys as $nindex)
			{
				$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ? $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
				if($matrix[$oindex][$nindex] > $maxlen)
				{
					$maxlen = $matrix[$oindex][$nindex];
					$omax = $oindex + 1 - $maxlen;
					$nmax = $nindex + 1 - $maxlen;
				}
			}
		}
		if($maxlen == 0) 
		return array(array('d'=>$old, 'i'=>$new));
		
		return array_merge(
		$this->diff(array_slice($old, 0, $omax), array_slice($new, 0, $nmax)),
		array_slice($new, $nmax, $maxlen),
		$this->diff(array_slice($old, $omax + $maxlen), array_slice($new, $nmax + $maxlen)));
	}
	
	function htmlDiff($old, $new)
	{
		$diff = $this->diff(explode(' ', $old), explode(' ', $new));
		foreach($diff as $k)
		{
			if(is_array($k))
			$ret .= (!empty($k['d'])?"<del>".implode(' ',$k['d'])."</del> ":'').
			(!empty($k['i'])?"<ins>".implode(' ',$k['i'])."</ins> ":'');
			else $ret .= $k . ' ';
		}
		return $ret;
	}
	
	/**
	* Still needs some work
	*/
	function sideDiff($oldf,$newf)
	{
		$orig = array();
		$new = array();
		$diff = $this->diff(explode(' ',htmlentities(trim($oldf))), explode(' ',htmlentities(trim($newf))));
		foreach($diff as $word)
		{
			if(is_array($word))
			{
				$orig[] = '<del>';
				foreach($word[d] as $d)
				{
					if(!empty($d))
					$orig[] = trim($d);
				}
				$orig[] = '</del>';
				$new[] = '<ins>';
				foreach($word[i] as $i)
				{
					$new[] = trim($i);
				}
				$new[] = '</ins>';
				
			}else{
				$orig[] = $word;
				$new[] = $word;
			}
		}
		
		return array('old'=>$orig,'new'=>$new);
	}
	
	function PHPDiff($old,$new) 
	{
		# split the source text into arrays of lines
		$t1 = explode("\n",$old);
		$x=array_pop($t1); 
		if ($x>'') $t1[]="$x\n\\ No newline at end of file";
		$t2 = explode("\n",$new);
		$x=array_pop($t2); 
		if ($x>'') $t2[]="$x\n\\ No newline at end of file";
		
		# build a reverse-index array using the line as key and line number as value
		# don't store blank lines, so they won't be targets of the shortest distance
		# search
		foreach($t1 as $i=>$x) if ($x>'') $r1[$x][]=$i;
		foreach($t2 as $i=>$x) if ($x>'') $r2[$x][]=$i;
		
		$a1=0; $a2=0;   # start at beginning of each list
		$actions=array();
		
		# walk this loop until we reach the end of one of the lists
		while ($a1<count($t1) && $a2<count($t2)) 
		{
			# if we have a common element, save it and go to the next
			if ($t1[$a1]==$t2[$a2]) { $actions[]=4; $a1++; $a2++; continue; }
			
			# otherwise, find the shortest move (Manhattan-distance) from the
			# current location
			$best1=count($t1); $best2=count($t2);
			$s1=$a1; $s2=$a2;
			while(($s1+$s2-$a1-$a2) < ($best1+$best2-$a1-$a2)) 
			{
				$d=-1;
				foreach((array)@$r1[$t2[$s2]] as $n) 
				if ($n>=$s1) { $d=$n; break; }
				if ($d>=$s1 && ($d+$s2-$a1-$a2)<($best1+$best2-$a1-$a2))
				{ $best1=$d; $best2=$s2; }
				$d=-1;
				foreach((array)@$r2[$t1[$s1]] as $n) 
				if ($n>=$s2) { $d=$n; break; }
				if ($d>=$s2 && ($s1+$d-$a1-$a2)<($best1+$best2-$a1-$a2))
				{ $best1=$s1; $best2=$d; }
				$s1++; $s2++;
			}
			while ($a1<$best1) { $actions[]=1; $a1++; }  # deleted elements
				while ($a2<$best2) { $actions[]=2; $a2++; }  # added elements
		}
		
		# we've reached the end of one list, now walk to the end of the other
		while($a1<count($t1)) { $actions[]=1; $a1++; }  # deleted elements
			
		while($a2<count($t2)) { $actions[]=2; $a2++; }  # added elements
				
		# and this marks our ending point
		$actions[]=8;
				
		# now, let's follow the path we just took and report the added/deleted
		# elements into $out.
		$op = 0;
		$x0=$x1=0; $y0=$y1=0;
		$out = array();
		foreach($actions as $act) 
		{
			
			if ($act==1) { $op|=$act; $x1++; continue; }
			if ($act==2) { $op|=$act; $y1++; continue; }
			if ($op>0) 
			{
				$xstr = ($x1==($x0+1)) ? $x1 : ($x0+1).",$x1";
				$ystr = ($y1==($y0+1)) ? $y1 : ($y0+1).",$y1";
				if ($op==1) $out[] = "<li class=\"end\">{$xstr}d{$y1}</li>";
				elseif ($op==3) $out[] = "<li class=\"end\">{$xstr}c{$ystr}</li>";
				while ($x0<$x1) { $out[] = '<li class="del"> - '.$t1[$x0].''; $x0++; }   # deleted elems
					if ($op==2) $out[] = "<li class=\"end\">{$x1}a{$ystr}</li>";
					elseif ($op==3) $out[] = '<li class="end">---</li>';
					while ($y0<$y1) { $out[] = '<li class="ins"> +  '.$t2[$y0] .''; $y0++; }   # added elems
			}
			$x1++; $x0=$x1;
			$y1++; $y0=$y1;
			$op=0;
		}
		$out[] = '';
		return join("\n",$out);
	}
	
	/**
	 * @name svnLogParse
	 * @public
	 * @param $comment
	 * @return text
	 * @note This will replace {ticket#ticketnumber} with a link to the ticket
	 * @note this will replace {wiki:pagename} with a link to the wiki page
	*/
	function svnLogParse($comment, $project)
	{
		// 	 $comment = str_replace("ticket#27", "{ticket#27}",$comment);
		
		$search = array(
				'/{ticket#(\d{0,})}/i', //ticket links: eg {ticket:23}
				'/{wiki:(.*?)}/is', //wiki links: eg{milestone:a1alpha}
				);
						
		$replace = array(
				'<A href="index.php?option=com_jhtraq&view=tickets&layout=view&project='.$project->slug.'&ticket=$1">#$1</a>',
				'<A href="index.php?option=com_jhtraq&view=wiki&project='.$project->slug.'&page=$1">$1</a>',
				);
		$body = preg_replace ($search, $replace, $comment);
										 
		return $body;	 
	}
	
}
   
   
  
  
		   
		   
   


	
